package com.suray.wcs.service.pojo;

import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.JSONSerializable;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.fasterxml.jackson.annotation.JsonValue;
import com.suray.basic.wcs.node.WCSNodeModule;
import com.suray.basic.wcs.path.core.Node;
import com.suray.basic.wcs.time.bo.WCSTimeModuleBO;
import com.suray.basic.wcs.time.bo.WCSTimeModuleResultBO;
import com.suray.basic.wcs.utils.*;
import com.suray.commin.core.utils.SpringContextHolder;
import com.suray.commin.exception.RgvReTaskException;
import com.suray.type.ErrorLevel;
import com.suray.wcs.res.enums.PalletStatus;
import com.suray.wcs.res.enums.RgvReTaskType;
import com.suray.wcs.res.enums.RgvStatus;
import com.suray.wcs.res.msgparse.HeartBaseResult;
import com.suray.wcs.res.msgparse.HeartSendBean;
import com.suray.wcs.service.core.path.api.impl.PathHandleImpl;
import com.suray.wcs.service.core.util.LockNodeManager;
import com.suray.wcs.service.enums.CodeType;
import com.suray.wcs.res.enums.RgvType;
import com.suray.wcs.service.execption.InterruptTaskException;
import com.suray.commin.exception.OrderExecuteException;
import com.suray.wcs.service.pojo.rgv.action.RgvCommandAction;
import com.suray.wcs.service.pojo.rgv.action.RgvTaskAction;
import com.suray.wcs.service.pojo.rgv.action.util.RgvTaskMode;
import com.suray.wcs.service.pojo.rgv.rgv.protocol.RgvProtocol;
import com.suray.wcs.service.pojo.rgv.rgv.protocol.base.RgvBaseMessage;
import com.suray.wcs.service.pojo.rgv.rgv.protocol.message.RgvLifeRecMessage;
import com.suray.wcs.service.pojo.rgv.rgv.protocol.util.RgvCargoStatus;
import com.suray.wcs.service.rescontact.ResultContainer;
import com.suray.wcs.service.system.entity.RgvDB;
import com.suray.wcs.service.system.entity.TaskDB;
import com.suray.wcs.service.system.service.impl.CodeDBServiceImpl;
import com.suray.wcs.service.thread.RgvExecuteThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;


public class Rgv extends BaseRgv {
    private static final String VERSION_HEAD = "RES+3.1_v";

    private CodeDBServiceImpl codedbService = SpringContextHolder.getBean(CodeDBServiceImpl.class);
    private PathHandleImpl pathHandleImpl = SpringContextHolder.getBean(PathHandleImpl.class);
    private Logger log = LoggerFactory.getLogger(this.getClass());
    /**
     * 小车的DB对象
     */
    private RgvDB rgvDB;
    /**
     * 执行小车任务的线程
     */
    @JSONField(serialize = false)
    private RgvExecuteThread rgvExecuteThread;
    /**
     * 小车运行时的排斥状态, 详见{@link RejectStatus}
     */
    @JSONField(serialize = false)
    private RejectStatus rejectStatus;

    /**
     * 小车运行时的排斥状态信息, 详见{@link RejectStatus}
     */
    @JSONField(serialize = false)
    private String rejectStatusInfo;

    /**
     * 小车分配的任务
     */
    private TaskDB curTask;

    /**
     * 小车故障任务的任务id
     */
    private String errorTaskId;

    /**
     * 小车分配的节点集合
     */
    @JSONField(serialize = false)
    private volatile List<Node> executeNodeList = new ArrayList<>();
    /**
     * 单巷道阻塞的小车
     */
    @JSONField(serialize = false)
    private List<Rgv> waitSingleRoadRgvS;

    /**
     * 充电或接驳点有小车
     */
    @JSONField(serialize = false)
    private List<Rgv> waitChaOrConRgvList;
    /**
     * 小车剩余需要行驶的路径
     */
    @JSONField(serialize = false)
    private volatile List<Node> waitExecuteNodeList;

    /**
     * 小车的心跳对象
     */
    @JSONField(serialize = false)
    private HeartSendBean rgvHeart;
    /**
     * 排斥车辆
     */
    @JSONField(serialize = false)
    private Rgv rejectRgv;
    /**
     * 等待车辆
     */
    @JSONField(serialize = false)
    private volatile Rgv waitRgv;

    /**
     * 小车分配的任务
     */
    @JSONField(serialize = false)
    private List<TaskDB> waitTasks;

    /**
     * 充电或接驳点有小车
     */
    @JSONField(serialize = false)
    private Boolean waitConnectPointNoGoods;
    /**
     * 已经发送给小车的行驶节点
     */
    private ArrayList<Node> waitReleaseNode = new ArrayList<>();

    /**
     * 小车是否是中断状态
     */

    private boolean isInterrupt;

    private RgvReTaskType reTaskType;

    public Integer getCurResTaskNo() {
        return curResTaskNo;
    }

    /**
     * 发送给RES的任务号
     */
    private Integer curResTaskNo;

    /**
     * 车辆当前路径及消耗值
     */
    @JSONField(serialize = false)
    private WCSTimeModuleResultBO wcsTimeModuleResultBO;


    /**
     * 小车通讯
     */
    private RgvProtocol rgvProtocol;

    /**
     * 小车指令信息
     */
    private RgvCommandAction cmdAction;

    /**
     * 小车任务信息
     */
    private RgvTaskAction taskAction;

    /**
     * 是否在发送地图
     */
    private boolean sendMapFlag = false;

    /**
     * 状态描述
     */
    protected String statusDescription;

    /**
     * 是否有驱动器故障
     */
    private boolean hasDriverError;

    /**
     * 车上货物所属任务Id
     */
    private Integer cargoTaskId;

    /**
     * 是否在下载固件
     */
    private boolean updateFirewareFlag;

    /**
     * 是否在提取日志
     */
    private boolean extractLogFlag;
    /**
     * 托盘循环
     */
    protected boolean palletLoop;

    /**
     * 换向循环
     */
    protected boolean reversLoop;
    /**
     * 空载循环
     */
    protected boolean unLoadedLoop;
    /**
     * 载货循环
     */
    protected boolean loadedLoop;

    public boolean isBA() {
        return isBA;
    }

    public void setBA(boolean BA) {
        isBA = BA;
    }

    /**
     * 移库循环
     */
    protected boolean transferLoop;

    /**
     * 停止心跳交互
     */
    protected volatile boolean stopHeart;

    //小车里程
    private long odo;
    //小车换向和托盘顶升次数
    private long act;

    /**
     * 行驶信息
     */
    private DrivingParam drivingParam;

    /**
     * 升降信息
     */
    private LiftParam liftParam;

    /**
     * res信息
     */
    private ResParam resParam;

    /**
     * 通过指令获取托盘条码（RFID）标记，指令结果需按8个字节解析
     */
    private boolean isBA;

    private RgvTaskMode rgvTaskMode;

    /**
     * 穿梭车的电池信息
     */
    private RgvChargeInfo rgvChargeInfo;

    /**
     * 小车故障
     */
    private RgvError rgvError;

    private boolean initOk;

    /**
     * 每一个DB对象对应一个业务对象
     *
     * @param rgvDB
     */
    public Rgv(RgvDB rgvDB) {
        this.rgvDB = rgvDB;
        this.resParam = new ResParam();
        this.drivingParam = new DrivingParam();
        this.liftParam = new LiftParam();
        if (checkRgvType(RgvType.FIVE_POINT_FOUR_TL)) {
            rgvProtocol = new RgvProtocol(this);
            cmdAction = new RgvCommandAction();
            taskAction = new RgvTaskAction();
        }
        this.offLinePing();
        this.reTaskType = RgvReTaskType.INVALID;

        rgvTaskMode = RgvTaskMode.NORMAL;
        this.hasPallet = RgvCargoStatus.INVALID;

        rgvError = new RgvError();

        initOk = false;
    }

    public boolean isInitOk() {
        return initOk;
    }

    public void setInitOk(boolean initOk) {
        this.initOk = initOk;
    }

    public RgvError getRgvError() {
        return rgvError;
    }

    public void setBatterBalanceError(ErrorLevel errorLevel) {
        this.rgvError.setBatteryError(errorLevel);
    }

    public void changeReTaskType(RgvReTaskType reTaskType) {
        this.reTaskType = reTaskType;
    }

    public RgvTaskMode getRgvTaskMode() {
        return rgvTaskMode;
    }

    public void setRgvTaskMode(RgvTaskMode rgvTaskMode) {
        this.rgvTaskMode = rgvTaskMode;
    }

    public DrivingParam getDrivingParam() {
        return drivingParam;
    }

    public LiftParam getLiftParam() {
        return liftParam;
    }

    public ResParam getResParam() {
        return resParam;
    }

    public boolean isStopHeart() {
        return stopHeart;
    }

    public void setStopHeart(boolean stopHeart) {
        this.stopHeart = stopHeart;
    }

    public long getOdo() {
        return odo;
    }

    public void addOdo(long odo) {
        this.odo += odo;
    }

    public void setOdo(long odo) {
        this.odo = odo;
    }

    public long getAct() {
        return act;
    }

    public void addAct(long act) {
        this.act += act;
    }

    public void setAct(long act) {
        this.act = act;
    }

    public boolean isPalletLoop() {
        return palletLoop;
    }

    public void setPalletLoop(boolean palletLoop) {
        this.palletLoop = palletLoop;
    }

    public boolean isReversLoop() {
        return reversLoop;
    }

    public void setReversLoop(boolean reversLoop) {
        this.reversLoop = reversLoop;
    }

    public boolean isUnLoadedLoop() {
        return unLoadedLoop;
    }

    public void setUnLoadedLoop(boolean unLoadedLoop) {
        this.unLoadedLoop = unLoadedLoop;
    }

    public boolean isLoadedLoop() {
        return loadedLoop;
    }

    public void setLoadedLoop(boolean loadedLoop) {
        this.loadedLoop = loadedLoop;
    }

    public boolean isTransferLoop() {
        return transferLoop;
    }

    public void setTransferLoop(boolean transferLoop) {
        this.transferLoop = transferLoop;
    }

    public String getErrorTaskId() {
        return errorTaskId;
    }

    /**
     * 获取当前任务的任务id
     */
    public void generalErrorTaskId() {
        if (curTask != null) {
            errorTaskId = curTask.getTaskId().toString();
        } else {
            errorTaskId = null;
        }
    }

    public void setErrorTaskId(String errorTaskId) {
        this.errorTaskId = errorTaskId;
    }

    public boolean isUpdateFirewareFlag() {
        return updateFirewareFlag;
    }

    public void setUpdateFirewareFlag(boolean updateFirewareFlag) {
        this.updateFirewareFlag = updateFirewareFlag;
    }

    public boolean isExtractLogFlag() {
        return extractLogFlag;
    }

    public void setExtractLogFlag(boolean extractLogFlag) {
        this.extractLogFlag = extractLogFlag;
    }

    public RgvDB getRgvDB() {
        return rgvDB;
    }

    public void setRgvDB(RgvDB Rgvdb) {
        this.rgvDB = Rgvdb;
    }

    public List<Rgv> getWaitSingleRoadRgvS() {
        return waitSingleRoadRgvS;
    }

    public void setWaitSingleRoadRgvS(List<Rgv> waitSingleRoadRgvS) {
        this.waitSingleRoadRgvS = waitSingleRoadRgvS;
    }

    public List<Rgv> getWaitChaOrConRgvList() {
        return waitChaOrConRgvList;
    }

    public void setWaitChaOrConRgvList(List<Rgv> waitChaOrConRgvList) {
        this.waitChaOrConRgvList = waitChaOrConRgvList;
    }

    public RgvExecuteThread getRgvExecuteThread() {
        return rgvExecuteThread;
    }

    public void setRgvExecuteThread(RgvExecuteThread rgvExecuteThread) {
        this.rgvExecuteThread = rgvExecuteThread;
    }

    public RejectStatus getRejectStatus() {
        return rejectStatus;
    }

    public void setRejectStatus(RejectStatus rejectStatus) {
        this.rejectStatus = rejectStatus;
    }

    public String getRejectStatusInfo() {
        return rejectStatusInfo;
    }

    public void setRejectStatusInfo(String rejectStatusInfo) {
        this.rejectStatusInfo = rejectStatusInfo;
    }

    public Rgv getRejectRgv() {
        return rejectRgv;
    }

    public void setRejectRgv(Rgv rejectRgv) {
        this.rejectRgv = rejectRgv;
    }

    public Rgv getWaitRgv() {
        return waitRgv;
    }

    public void setWaitRgv(Rgv waitRgv) {
        this.waitRgv = waitRgv;
    }

    public List<TaskDB> getWaitTasks() {
        return waitTasks;
    }

    public void setWaitTasks(List<TaskDB> waitTasks) {
        this.waitTasks = waitTasks;
    }

    public Boolean getWaitConnectPointNoGoods() {
        return waitConnectPointNoGoods;
    }

    public void setWaitConnectPointNoGoods(Boolean waitConnectPointNoGoods) {
        this.waitConnectPointNoGoods = waitConnectPointNoGoods;
    }

    public HeartSendBean getRgvHeart() {
        return rgvHeart;
    }

    public void setRgvHeart(HeartSendBean rgvHeart) {
        this.rgvHeart = rgvHeart;
    }

    public boolean isSameMapVersion() {
        return isSameMapVersion;
    }

    public void setSameMapVersion(boolean isSameMapVersion) {
        this.isSameMapVersion = isSameMapVersion;
    }

    public Integer getCurrSegment() {
        return currSegment;
    }

    public void setCurrSegment(Integer currSegment) {
        this.currSegment = currSegment;
    }

    public Integer getSegmentLocation() {
        return segmentLocation;
    }

    public void setSegmentLocation(Integer segmentLocation) {
        this.segmentLocation = segmentLocation;
    }

    public TaskDB getCurTask() {
        return curTask;
    }

    public void setCurTask(TaskDB curTask) {
        this.curTask = curTask;
    }

    public void setCurResTaskNo(Integer curResTaskNo) {
        this.curResTaskNo = curResTaskNo;
    }

    public List<Node> getExecuteNodeList() {
        return executeNodeList;
    }

    public void setExecuteNodeList(List<Node> executeNodeList) {
        this.executeNodeList = executeNodeList;
    }

    public List<Node> getWaitExecuteNodeList() {
        return waitExecuteNodeList;
    }

    public void setWaitExecuteNodeList(List<Node> waitExecuteNodeList) {
        this.waitExecuteNodeList = waitExecuteNodeList;
    }

    public ArrayList<Node> getWaitReleaseNode() {
        return waitReleaseNode;
    }

    public void setWaitReleaseNode(ArrayList<Node> waitReleaseNode) {
        this.waitReleaseNode = waitReleaseNode;
    }

    public void addWaitReleaseNode(Node node) {
        this.waitReleaseNode.add(node);
    }

    public RgvProtocol getRgvProtocol() {
        return rgvProtocol;
    }

    public void setRgvProtocol(RgvProtocol rgvProtocol) {
        this.rgvProtocol = rgvProtocol;
    }

    public RgvCommandAction getCmdAction() {
        return cmdAction;
    }

    public void setCmdAction(RgvCommandAction cmdAction) {
        this.cmdAction = cmdAction;
    }

    public RgvTaskAction getTaskAction() {
        return taskAction;
    }

    public void setTaskAction(RgvTaskAction taskAction) {
        this.taskAction = taskAction;
    }

    public boolean isSendMapFlag() {
        return sendMapFlag;
    }

    public void setSendMapFlag(boolean sendMapFlag) {
        this.sendMapFlag = sendMapFlag;
    }

    public String getStatusDescription() {
        return statusDescription;
    }

    public void setStatusDescription(String statusDescription) {
        this.statusDescription = statusDescription;
    }

    public boolean isHasDriverError() {
        return hasDriverError;
    }

    public void setHasDriverError(boolean hasDriverError) {
        this.hasDriverError = hasDriverError;
    }

    public Integer getCargoTaskId() {
        return cargoTaskId;
    }

    public void setCargoTaskId(Integer cargoTaskId) {
        this.cargoTaskId = cargoTaskId;
    }

    public String getSeries() {
        return getRgvName();
    }

    public RgvChargeInfo getRgvChargeInfo() {
        return rgvChargeInfo;
    }

    public void setRgvChargeInfo(RgvChargeInfo rgvChargeInfo) {
        this.rgvChargeInfo = rgvChargeInfo;
    }

    /**
     * 检测小车类型
     *
     * @param rgvType
     * @return
     */
    public boolean checkRgvType(RgvType rgvType) {
        if (getRgvDB().getRgvType() == RgvType.FIVE_POINT_FOUR_TS.getValue()) {
            if (rgvType.equals(RgvType.FIVE_POINT_FOUR_TL)) {
                return true;
            }
        }

        if (rgvType == RgvType.RGV_SEER_COMM) {
            int type = getRgvDB().getRgvType();
            if (type == RgvType.RGV_SIX_POINT_ZERO.getValue()
                || type == RgvType.RGV_ROLLER.getValue()
                || type == RgvType.RGV_SON_MOTHER.getValue()
                || type == RgvType.RGV_FORK.getValue()
            ) {
                return true;
            }
        }

        return getRgvDB().getRgvType().equals(rgvType.getValue());
    }

    /**
     * 排斥状态
     *
     * @author
     */
    public enum RejectStatus implements JSONSerializable {

        /**
         * 正常运行状态
         */
        NONE(1, "正常运行状态"),
        /**
         * 排斥等待状态
         */
        WAIT(2, "排斥等待状态"),
        /**
         * 让路状态
         */
        AVOIDING(3, "让路状态"),
        /**
         * 绕路状态
         */
        DETOURING(4, "绕路状态"),
        /**
         * 无法恢复的死锁状态
         */
        DEADLOCK(5, "死锁状态");

        @JsonValue
        public String getDescription() {
            return description;
        }

        private int rejectStatus;
        private String description;

        RejectStatus(int rejectStatus, String description) {
            this.rejectStatus = rejectStatus;
            this.description = description;
        }

        @Override
        public String toString() {
            return description;
        }

        public static RgvStatus parseStatus(int status) {
            RgvStatus[] rgvStatuses = RgvStatus.values();
            for (RgvStatus rgvStatus : rgvStatuses) {
                if (rgvStatus.getRgvStatus() == status) {
                    return rgvStatus;
                }
            }
            throw new RuntimeException("排斥状态异常！");
        }

        @Override
        public void write(JSONSerializer jsonSerializer, Object o, Type type, int i) throws IOException {
            jsonSerializer.write(this.getDescription());
        }
    }

    /**
     * @return 小车名字
     */
    public String getRgvName() {
        return rgvDB.getRgvNo() + "号小车";
    }


    @Override
    public String toString() {
        return getRgvName() + "Rgv{" +
                "curLocation=" + curLocation +
                ", battery=" + battery +
                ", rgvStatus=" + rgvStatus +
                '}';
    }

    public boolean isInterrupt() {
        return isInterrupt;
    }

    public void setInterrupt(boolean interrupt) {
        isInterrupt = interrupt;
    }

    public void checkInterrupt(String msg, long checkTime) {
        if (reTaskType != RgvReTaskType.INVALID) {
            log.info(reTaskType.toString());
            reTaskType = RgvReTaskType.INVALID;
            throw new RgvReTaskException(reTaskType.toString());
        }

        if (this.isInterrupt) {
            log.error("中断RGV, In ->" + msg);
            setInterrupt(false);
            throw new InterruptTaskException("中断RGV, In ->" + msg);
        }
        if (this.getCurLocation() == null && this.getCurTask() != null) {
            log.error(this.getRgvName() + "任务中断，小车被重启过!");
            throw new OrderExecuteException(this.getRgvDB().getRgvNo(), 998, "小车重启，任务执行失败!");
        }
        if (this.rgvDB.getIsCalibration() && this.palletStatus == PalletStatus.UP
                && this.getHasPallet() == RgvCargoStatus.NO_CARGO && this.getCurTask() != null) {
            log.error(this.getRgvName() + "小车执行过程中货物丢失,请及时检查!");
            throw new OrderExecuteException(this.getRgvDB().getRgvNo(), 996, "小车执行过程中货物丢失,请及时检查!");
        }
        if (this.getCurResTaskNo() != null) {
            setStatusDescription(msg);
            HeartBaseResult receiverResult = ResultContainer.getContainer(this).getResult(this.getCurResTaskNo());
            if (receiverResult != null) {
                if (receiverResult.getTaskResult() != 0 && receiverResult.getTaskResult() != 1
                        && receiverResult.getTaskResult() != 2 && receiverResult.getRetDate().getTime() >= checkTime) {
                    this.setRgvStatus(RgvStatus.ERROR);
                    String message = codedbService.getCodeDescByFault(receiverResult.getTaskResult(), CodeType.RES_ERROR_CODE);
                    this.setErrorMessage(message);
                    log.error("检测到小车出现故障, In ->" + msg);
                    throw new OrderExecuteException(this.getRgvDB().getRgvNo(), receiverResult.getTaskResult(), this.getErrorMessage());
                }
            }

            if (checkRgvType(RgvType.FIVE_POINT_FOUR_TL)) {
                RgvBaseMessage message = ResultContainer.getContainer(this).getReceiveMessage(this.getCurResTaskNo());
                if (message instanceof RgvLifeRecMessage) {
                    int result = ((RgvLifeRecMessage) message).getResult();

                    if (result != 0 && result != 1 && result != 2 && message.getMessgeTime() > checkTime) {
                        this.setRgvStatus(RgvStatus.ERROR);
                        String message5 = codedbService.getCodeDescByFault(result, CodeType.RES_ERROR_CODE);
                        this.setErrorMessage(message5);
                        log.error("检测到小车出现故障, In ->" + msg);
                        throw new OrderExecuteException(this.getRgvDB().getRgvNo(), result, this.getErrorMessage());
                    }
                }
            }
        }

    }

    public WCSTimeModuleBO generateWCSTimeModuleBO() {
        WCSTimeModuleBO wcsTimeModuleBO = null;
        if (this.getRgvDB() != null) {
            wcsTimeModuleBO = new WCSTimeModuleBO();
            wcsTimeModuleBO.setSpeed(this.getRgvDB().getSpeed());
            wcsTimeModuleBO.setAccSpeed(this.getRgvDB().getAccSpeed());
            wcsTimeModuleBO.setDirectionTime(this.getRgvDB().getDirectionTime());
            wcsTimeModuleBO.setPalletDownTime(this.getRgvDB().getPalletDownTime());
            wcsTimeModuleBO.setPalletUpTime(this.getRgvDB().getPalletUpTime());
        }
        return wcsTimeModuleBO;
    }

    public WCSTimeModuleResultBO getWcsTimeModuleResultBO() {
        return wcsTimeModuleResultBO;
    }

    public void setWcsTimeModuleResultBO(WCSTimeModuleResultBO wcsTimeModuleResultBO) {
        this.wcsTimeModuleResultBO = wcsTimeModuleResultBO;
    }

    public void updateWcsTimeModuleResultBO(Coord currentCoord) {
        if (this.wcsTimeModuleResultBO != null && rgvStatus != RgvStatus.OFF_LINE && currentCoord != null) {
            Node node = this.wcsTimeModuleResultBO.getNode(currentCoord);
            if (node != null) {
                if (rgvStatus == RgvStatus.OFF_LINE || rgvStatus == RgvStatus.ERROR || curTask == null || rgvStatus == RgvStatus.NODE_STANDBY) {
                    if (rgvStatus == RgvStatus.OFF_LINE || rgvStatus == RgvStatus.ERROR) {
                        LockNodeManager.updateLockedNodeUnLockTimeIncrement(this, 10000);
                    } else if (rgvStatus == RgvStatus.NODE_STANDBY) {
                        LockNodeManager.updateLockedNodeUnLockTimeIncrement(this, 500);
                    } else {
                        LockNodeManager.updateLockedNodeUnLockTimeForNoTask(this);
                    }
                } else {
                    if (this.getCurTask() != null) {
                        node.calculatePassTime(this.getRgvDB().getSpeed(), 0, this.getRgvDB().getPalletUpTime(),
                                this.getRgvDB().getPalletDownTime(), this.getRgvDB().getDirectionTime(), this.getRgvDB().getRgvNo());
                    } else {
                        node.calculatePassTimeNoTask(this.getRgvDB().getSpeed(), 0, this.getRgvDB().getPalletUpTime(),
                                this.getRgvDB().getPalletDownTime(), this.getRgvDB().getDirectionTime());
                    }
                    node.cleanPassTime();
                    LockNodeManager.updateLockedNodeUnLockTime(this.wcsTimeModuleResultBO.getNodes(), this);
                    if (this.getCurTask() != null && this.getWcsTimeModuleResultBO() != null) {
                        WCSNodeModule.cleanWcsNodeModuleMapCacheRouteBy(this.getRgvDB().getRgvNo(), this.getWcsTimeModuleResultBO().getNodes(), this.getCurLocation());
                    }
                    if (this.waitExecuteNodeList != null) {
                        WCSNodeModule.updateWcsNodeModuleMapCacheRouteBy(this.waitExecuteNodeList, this.getRgvDB().getRgvNo(), this.getWcsTimeModuleResultBO().getNodeMap());
                    }
                }
            }
        } else {
            if (rgvStatus == RgvStatus.OFF_LINE || rgvStatus == RgvStatus.ERROR) {
                LockNodeManager.updateLockedNodeUnLockTimeIncrement(this, 10000);
            } else if (curTask == null) {
                LockNodeManager.updateLockedNodeUnLockTimeForNoTask(this);
            } else {
                LockNodeManager.updateLockedNodeUnLockTimeIncrement(this, 1000);
            }
        }
    }

    /**
     * 判断小车是否托盘顶升
     *
     * @return
     */
    public boolean isHasCargo() {
        if (checkRgvType(RgvType.FIVE_POINT_FOUR_TL)) {
            if (getCurTask() != null) {
                return PalletStatus.UP.equals(getPalletStatus()) || pathHandleImpl.analyzePalletStatus(getCurTask());
            } else {
                return PalletStatus.UP.equals(getPalletStatus()) || this.getCargoTaskId() != null;
            }
        } else {
            return PalletStatus.UP.equals(getPalletStatus());
        }
    }

    /**
     * 速度模式：新版本模式还是老版本模式
     * TRUE : 新模式， FALSE : 旧模式
     */
    public boolean versionCheck(int ver) {
        String version = resParam.getResVersion();
        if (version == null) {
            //未获取到小车版本, 默认老版本模式
            return false;
        }

        try {
            if (version.startsWith(VERSION_HEAD)) {
                String v = version.substring(VERSION_HEAD.length());
                String[] versionArray = v.split("\\.");
                int readVersion = Integer.valueOf(versionArray[0]) * 10000 + Integer.valueOf(versionArray[1]) * 100
                        + Integer.valueOf(versionArray[2]);
                return readVersion >= ver;
            }
        } catch (Exception e) {
            LoggerUtil.error(ModuleType.RES_20_RGV, LoggerType.INFO, version, getRgvName(),
                    VERSION_HEAD + "对比版本号:" + ver, this.getClass());
            LoggerUtil.error("版本检测出错!", this.getClass());
            WcsFuncUtil.exceptionLog(e, this.getClass());
        }

        return false;
    }
}
